﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace ResourceEditor.Core.ResourceDataObjects
{
    public abstract class ResourceData
    {
        internal abstract bool IsKeyExist(string key);
        internal abstract bool HasChanges { get; }
        internal abstract void SortByKey();
    }

    public class ResourceData<T> : ResourceData, IEnumerable<Data<T>>
    {
        #region Properties
        protected List<Data<T>> Items { get; set; }

        protected ResourceFile Container { get; private set; }
        #endregion

        #region Ctor
        internal ResourceData(ResourceFile container)
        {
            Container = container;
            Items = new List<Data<T>>();
        }
        #endregion

        #region Methods
        internal void AddFromFile(string key, T item)
        {
            Items.Add(new Data<T>(key, item, ItemState.Original));
        }

        public void Add(string key, T item)
        {
            if (Container.IsKeyExist(key))
            {
                throw new ArgumentException(string.Format(Messages.KeyExist, key));
            }

            Items.Add(new Data<T>(key, item, ItemState.Added));
        }

        public void Delete(string key)
        {
            this[key].State = ItemState.Deleted;
        }

        public void ChangeKey(string oldKey, string newKey)
        {
            if (Container.IsKeyExist(newKey))
            {
                throw new ArgumentException(string.Format(Messages.KeyExist, newKey));
            }

            this[oldKey].ChangeKey(newKey);
        }

        public void ChangeItem(string key, T newItem)
        {
            this[key].ChangeItem(newItem);
        }

        #endregion

        #region  ResourceData Members
        internal override bool IsKeyExist(string key)
        {
            return Items.Any(item => item.State != ItemState.Deleted && item.Key.ToLower() == key.ToLower());
        }

        internal override bool HasChanges
        {
            get
            {
                return Items.Any(item => item.State != ItemState.Original);
            }
        }

        internal override void SortByKey()
        {
            Items.Sort((item1, item2) => item1.Key.CompareTo(item2.Key));
        }

        #endregion

        #region IEnumerable<KeyValuePair<string,Values<T>>> Members

        public IEnumerator<Data<T>> GetEnumerator()
        {
            return Items.GetEnumerator();
        }

        #endregion

        #region IEnumerable Members

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        #endregion

        #region Indexer
        public Data<T> this[string key]
        {
            get
            {
                return Items.Find(item => item.Key == key && item.State != ItemState.Deleted);
            }
        }
        #endregion
    }
}
